package com.tj.common.util.test;

import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.ByteBuffer;
import java.util.Map;

import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.PutMethod;
import org.apache.commons.io.IOUtils;

@SuppressWarnings("unchecked")
public class HttpTestUtil {
    static HttpClient client;
    static {
        MultiThreadedHttpConnectionManager connectionManager = new MultiThreadedHttpConnectionManager();
        client = new HttpClient(connectionManager);
    }

    /**
     * create a post request to server, alternatively , you can specify the  content encoding that will be used when makeing request to server 
     * @param url
     * @param params
     * @return
     * @throws Exception
     */
    public static String httpPostForString(String url, Map params) throws Exception {
        return httpPostForString(url, params, null);
    }

    public static String httpPostForString(String url, Map params, String referer) throws Exception {
        String r = null;
        //        HttpClient client = new HttpClient();
        PostMethod method = new PostMethod(url);
        if (referer != null) {
            method.addRequestHeader(new Header("Referer", referer));
        }
        String encoding = "ISO-8859-1";
        if (params != null) {
            NameValuePair[] ps = new NameValuePair[params.size()];
            int counter = 0;
            for (Object sk : params.keySet()) {
                String k = (String) sk;
                if (encoding == null) {
                    ps[counter++] = new NameValuePair(k, (String) params.get(k));
                } else {
                    String ns = new String(((String) params.get(k)).getBytes(), encoding);
                    ps[counter++] = new NameValuePair(k, ns);
                }
            }
            method.setRequestBody(ps);
        }

        int statusCode = client.executeMethod(method);
        if (statusCode != HttpStatus.SC_OK) {
            InputStream ins = method.getResponseBodyAsStream();
            System.out.println(IOUtils.toString(ins));
            throw new Exception("Http request returns status code other than OK: " + statusCode + ", url is " + url);
        }
        InputStream ins = method.getResponseBodyAsStream();
        r = IOUtils.toString(ins);
        ins.close();
        method.releaseConnection();
        return r;
    }

    public static String httpGetForString(String url, Map params) throws Exception {
        return httpGetForString(url, params, null);
    }

    public static String httpGetForString(String url, Map params, String referer) throws Exception {
        String r = null;
        //        HttpClient client = new HttpClient();
        if (params != null) {
            StringBuffer buf = new StringBuffer();
            for (Object sk : params.keySet()) {
                String k = (String) sk;
                buf.append(k);
                buf.append('=');
                buf.append((String) params.get(k));
                buf.append("&");
            }
            if (buf.length() != 0) {
                buf.deleteCharAt(buf.length() - 1);
            }
            if (url.indexOf('?') > 0) {
                url = url + "&" + buf.toString();
            } else {
                url = url + "?" + buf.toString();
            }
        }

        GetMethod method = new GetMethod(url);
        if (referer != null) {
            method.addRequestHeader(new Header("Referer", referer));
        }
        int statusCode = client.executeMethod(method);
        if (statusCode != HttpStatus.SC_OK) {
            System.err.println("request url :" + url);
            throw new Exception("Http request returns status code other than OK: " + statusCode);
        }
        InputStream ins = method.getResponseBodyAsStream();
        r = IOUtils.toString(ins);
        ins.close();
        method.releaseConnection();
        return r;
    }

    public static String httpPutForString(String url, Map params, String referer) throws Exception {
        String r = null;
        //        HttpClient client = new HttpClient();
        PutMethod method = new PutMethod(url);
        if (referer != null) {
            method.addRequestHeader(new Header("Referer", referer));
        }
        String encoding = "ISO-8859-1";
        if (params != null) {
            NameValuePair[] ps = new NameValuePair[params.size()];
            int counter = 0;
            for (Object sk : params.keySet()) {
                String k = (String) sk;
                if (encoding == null) {
                    ps[counter++] = new NameValuePair(k, (String) params.get(k));
                } else {
                    String ns = new String(((String) params.get(k)).getBytes(), encoding);
                    ps[counter++] = new NameValuePair(k, ns);
                }
            }
            method.setQueryString(ps);
        }

        int statusCode = client.executeMethod(method);
        if (statusCode != HttpStatus.SC_OK) {
            throw new Exception("Http request returns status code other than OK: " + statusCode + ", url is " + url);
        }
        InputStream ins = method.getResponseBodyAsStream();
        r = IOUtils.toString(ins);
        ins.close();
        method.releaseConnection();
        return r;
    }

    static String[] values = new String[] { "nmonth1", "09", "nmonth1_new_value", "true", "nday1", "29", "nday1_new_value", "false", "startStation", "济南",
            "startStation_new_value", "false", "arriveStation", "上海", "arriveStation_new_value", "false", "rFlag", "1", "name_ckball", "value_ckball",
            "tFlagDC", "DC", "tFlagZ", "Z", "tFlagT", "T", "tFlagK", "K", "tFlagPK", "PK", "tFlagPKE", "PKE", "tFlagLK", "LK" };

    public static String httpPostForString2(String link, String[] params, String referer) throws IOException {
        HttpURLConnection con = (HttpURLConnection) new URL(link).openConnection();
        StringBuffer buf = new StringBuffer();
        con.setRequestMethod("POST");
        if (referer != null)
            con.addRequestProperty("Referer", referer);
        con.addRequestProperty("Content-Type", "application/x-www-form-urlencoded");

        con.setDoInput(true);
        con.setDoOutput(true);
        DataOutputStream out = new DataOutputStream(con.getOutputStream());
        for (int i = 0, len = params.length; i < len; i++) {
            buf.append(params[i++]);
            buf.append('=');
            buf.append(URLEncoder.encode(params[i], "UTF8"));
            buf.append("&");
        }
        out.writeBytes(buf.toString());
        out.flush();
        BufferedReader ins = new BufferedReader(new InputStreamReader(con.getInputStream()));
        buf.delete(0, buf.length());
        String s = null;
        while ((s = ins.readLine()) != null) {
            buf.append(s);
        }
        out.close();
        ins.close();
        return buf.toString();
    }

    public static byte[] httpPostForByte(String link, String[] params, String referer) throws IOException {
        HttpURLConnection con = (HttpURLConnection) new URL(link).openConnection();
        StringBuffer buf = new StringBuffer();
        con.setRequestMethod("POST");
        if (referer != null)
            con.addRequestProperty("Referer", referer);
        con.addRequestProperty("Content-Type", "application/x-www-form-urlencoded");

        con.setDoInput(true);
        con.setDoOutput(true);
        DataOutputStream out = new DataOutputStream(con.getOutputStream());
        for (int i = 0, len = params.length; i < len; i++) {
            buf.append(params[i++]);
            buf.append('=');
            buf.append(URLEncoder.encode(params[i], "UTF8"));
            buf.append("&");
        }
        out.writeBytes(buf.toString());
        out.flush();
        ByteArrayOutputStream outbuf = new ByteArrayOutputStream();
        byte[] bytebuf = new byte[1024];
        InputStream ins = con.getInputStream();
        while (true) {
            int count = ins.read(bytebuf);
            if (count <= 0)
                break;
            outbuf.write(bytebuf, 0, count);
        }
        outbuf.flush();
        outbuf.close();
        ins.close();
        return outbuf.toByteArray();
    }

    private static int Index_TrainNum = 2;
    private static int Index_Yingzuo = 11;
    private static int Index_Ruanzuo = 12;
    private static int Index_Yingwo = 13;
    private static int Index_Ruanwo = 14;
    private static int Index_Yideng = 15;
    private static int Index_Erdeng = 16;
    private static int Index_GaojiRuanwo = 17;

    public static String[] parseEntry(String s) {
        String[] r = new String[8];
        String[] ss = s.split(",");
        s = ss[Index_TrainNum];
        int index = s.indexOf('^');
        r[0] = s.substring(0, index);
        r[1] = ss[Index_Yingzuo];
        r[2] = ss[Index_Ruanzuo];
        r[3] = ss[Index_Yingwo];
        r[4] = ss[Index_Ruanwo];
        r[5] = ss[Index_Yideng];
        r[6] = ss[Index_Erdeng];
        r[7] = ss[Index_GaojiRuanwo];
        return r;
    }

    public static void main(String[] args) throws Exception {
        String content = httpPostForString2("http://dynamic.12306.cn/TrainQuery/iframeTrainInfoByStation.jsp", values,
                "http://dynamic.12306.cn/TrainQuery/trainInfoByStation.jsp");
        int start = 0;
        int end = 0;
        while (true) {
            start = content.indexOf("parent.mygrid.addRow", end);
            if (start == -1)
                break;
            end = content.indexOf(");", start);
            if (end == -1)
                break;
            System.out.println(content.substring(start, end));
            parseEntry(content.substring(start, end));
        }
    }
}
